package com.ecoolex.hotel.saas.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.hotel.saas.core.dao.PresaleCouponOrderDetailDAO;
import com.ecoolex.hotel.saas.core.util.CouponCodeUtil;
import com.ecoolex.hotel.saas.entity.PresaleCoupon;
import com.ecoolex.hotel.saas.entity.PresaleCouponExpirydate;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderDetail;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderDetail.Column;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderDetailExample;
import com.ecoolex.hotel.saas.entity.PresaleCouponOrderDetailExample.Criteria;
import com.ecoolex.hotel.saas.enums.PresaleCouponExpirydateStrategy;
import com.ecoolex.hotel.saas.enums.PresaleCouponOrderDetailStatus;

import java.time.Instant;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PresaleCouponOrderDetailManager {
	
    @Autowired
    private PresaleCouponOrderDetailDAO dao;
    
    @Autowired
    private PresaleCouponExpirydateManager presaleCouponExpirydateManager;
    
    @Autowired
    private CouponCodeUtil couponCodeUtil;
    
    public PresaleCouponOrderDetail create(Integer orderId, PresaleCoupon presaleCoupon, String createUser) {
    	PresaleCouponOrderDetail detail = new PresaleCouponOrderDetail();
    	detail.setOrderId(orderId);
    	detail.setPreCouponId(presaleCoupon.getPreCouponId());
    	detail.setName(presaleCoupon.getName());
    	detail.setCoverImage(presaleCoupon.getCoverImage());
    	detail.setRetailPrice(presaleCoupon.getRealPrice());
    	detail.setTotalPrice(presaleCoupon.getRealPrice());
    	detail.setDistributionSettleType(presaleCoupon.getDistributionSettleType());
    	detail.setDeleted(PresaleCouponOrderDetail.NOT_DELETED);
    	detail.setCreateUser(createUser);
    	detail.setCreateTime(Date.from(Instant.now()));
    	detail.setUpdateUser(createUser);
    	detail.setUpdateTime(Date.from(Instant.now()));
    	dao.insert(detail);
    	return detail;
    }
    
    public void update(PresaleCouponOrderDetail detail, String updateUser) {
		PresaleCouponExpirydate couponExpirydate = presaleCouponExpirydateManager.get(detail.getPreCouponId());
		Date startExpirydate = null;
		Date endExpirydate = null;
		if(PresaleCouponExpirydateStrategy.FIXED.equal(couponExpirydate.getExpirydateStrategy())) {
			//固定有效期
			startExpirydate = couponExpirydate.getFixedStartExpirydate();
			endExpirydate = couponExpirydate.getFixedEndExpirydate();
		}else if(PresaleCouponExpirydateStrategy.DYNAMIC.equal(couponExpirydate.getExpirydateStrategy())) {
			//动态有效期
			startExpirydate = Date.from(Instant.now());
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.DATE, couponExpirydate.getDynamicExpirydateValue());
			endExpirydate = calendar.getTime();
		}
		detail.setStatus(PresaleCouponOrderDetailStatus.WAIT_USE.real());
		detail.setCouponCode(createCouponCode(detail.getPreCouponId()));
		detail.setStartExpirydate(startExpirydate);
		detail.setEndExpirydate(endExpirydate);
		detail.setUpdateUser(updateUser);
    	detail.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(detail);
    }
    
    private String createCouponCode(Integer preCouponId) {
    	String couponCode = couponCodeUtil.buildCode(preCouponId);
    	PresaleCouponOrderDetail orderDetail = getByCouponCode(couponCode);
    	if(Check.notNull(orderDetail)) {
    		createCouponCode(preCouponId);
    	}
    	return couponCode;
    }
    
    public void deleteByOrderId(Integer orderId, String updateUser) {
    	List<PresaleCouponOrderDetail> list = queryByOrderId(orderId);
    	list.forEach(d -> {
    		d.setDeleted(PresaleCouponOrderDetail.IS_DELETED);
    		d.setUpdateUser(updateUser);
    		d.setUpdateTime(Date.from(Instant.now()));
    		dao.updateByPrimaryKeySelective(d, Column.deleted,Column.updateUser,Column.updateTime);
    	});
    }
    
    public List<PresaleCouponOrderDetail> queryByOrderId(Integer orderId){
    	PresaleCouponOrderDetailExample example = new PresaleCouponOrderDetailExample();
    	Criteria criteria = example.createCriteria();
    	criteria.andOrderIdEqualTo(orderId).andDeletedEqualTo(PresaleCouponOrderDetail.NOT_DELETED);
    	return dao.selectByExample(example);
    }
    
    /**
     * 券码核销
     * @param couponCode
     * @param updateUser
     * @return
     */
    public PresaleCouponOrderDetail couponCodeVerify(String couponCode, String updateUser) {
    	PresaleCouponOrderDetail orderDetail = getByCouponCode(couponCode);
    	BizAssert.isTrue(Check.notNull(orderDetail),ResultCode.BIZ.build(1), "券码输入错误");
    	Date now = Date.from(Instant.now());
    	BizAssert.isTrue(Check.isLessThanEqual(orderDetail.getStartExpirydate(), now) &&
    		Check.isGreatThanEqual(orderDetail.getEndExpirydate(), now),
    		ResultCode.BIZ.build(2),
    		"券码不在有效期内");
    	orderDetail.setStatus(PresaleCouponOrderDetailStatus.VERIFY.real());
    	orderDetail.setUpdateUser(updateUser);
    	orderDetail.setUpdateTime(now);
		dao.updateByPrimaryKeySelective(orderDetail, Column.status,Column.updateUser,Column.updateTime);
		return orderDetail;
    }
    
    /**
     * 取消核销
     * @param orderId
     * @param updateUser
     * @return
     */
    public PresaleCouponOrderDetail cancelVerify(Integer orderId, String updateUser) {
    	List<PresaleCouponOrderDetail> list = queryByOrderId(orderId);
    	PresaleCouponOrderDetail orderDetail = list.get(0);
    	orderDetail.setStatus(PresaleCouponOrderDetailStatus.WAIT_USE.real());
    	orderDetail.setUpdateUser(updateUser);
    	orderDetail.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(orderDetail, Column.status,Column.updateUser,Column.updateTime);
		return orderDetail;
    }
    
    public PresaleCouponOrderDetail getByCouponCode(String couponCode) {
    	PresaleCouponOrderDetailExample example = new PresaleCouponOrderDetailExample();
    	Criteria criteria = example.createCriteria();
    	criteria.andCouponCodeEqualTo(couponCode);
    	return dao.selectOneByExample(example);
    }
    
    public List<PresaleCouponOrderDetail> queryExpire(Date time, int size){
    	PresaleCouponOrderDetailExample example = new PresaleCouponOrderDetailExample();
    	Criteria criteria = example.createCriteria();
    	criteria.andStatusEqualTo(PresaleCouponOrderDetailStatus.WAIT_USE.real())
    	.andEndExpirydateLessThanOrEqualTo(time);
    	return dao.selectByExample(example);
    }
    
    public void expire(PresaleCouponOrderDetail detail, String updateUser) {
    	detail.setStatus(PresaleCouponOrderDetailStatus.EXPIRE.real());
    	detail.setUpdateUser(updateUser);
    	detail.setUpdateTime(Date.from(Instant.now()));
		dao.updateByPrimaryKeySelective(detail, Column.status,Column.updateUser,Column.updateTime);
    }
}